import requests
import json
import os

headers = {
    'Accept': 'application/json, text/plain, */*',
    'Accept - Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Connection': 'keep-alive',
    'csrf': 'J6UKIKREG',
    'Cookie': '_ga=GA1.2.2065300548.1640428004; _gid=GA1.2.758308048.1640428004; gtoken=JBJAbTTZw0dB; gid=b1054c0d-2405-4a66-af33-d58e9422ad74; JSESSIONID=17424rcckc6gd1x5aronml5v6t; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1640431640,1640431834,1640431891,1640434012; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1640434012; kw_token=J6UKIKREG',
    'Host': 'www.kuwo.cn',
    'Referer': f'http://www.kuwo.cn',
    'User-Agent': 'Mozilla/5.0 '
}


def get():
    sou_name = input('输入要搜索的歌手或歌曲名：')
    # 第一页开始获取
    url = f'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={sou_name}&pn=1&rn=30&httpsStatus=1'
    sum_num = int(json.loads(requests.get(url=url, headers=headers).text).get('data').get('total'))
    print(f'共有：{sum_num // 30 + 1}页，{sum_num}首歌')
    num = 1  # 页数的变量
    num_yy = 1  # 歌曲数的变量
    data_list = []
    # 网页歌曲数量逻辑
    while num <= sum_num // 30 + 1:  # 最多只能遍历到最后一页
        url = f'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={sou_name}&pn={num}'
        get_url01 = requests.get(url=url, headers=headers)
        get_url01.encoding = get_url01.apparent_encoding
        json_data01 = json.loads(get_url01.text)
        reqId = json_data01.get('reqId')  # reqId的添加可以获得到付费音乐
        for i in json_data01.get('data').get('list'):
            print(f'序号：{num_yy} | 歌曲：{i.get("name")} | 歌手：{i.get("artist")} | 时间：{i.get("songTimeMinutes")}')
            data_list.append([reqId, i.get('rid'), i.get('name'), i.get('artist')])
            num_yy += 1
        # 换页操作
        while True:
            num01 = input('是否需要换一页yes或no(可以大写YES或NO)：')
            if num01 == 'yes' or num01 == "YES":
                num += 1  # 页数的更换加1
                break
            elif num01 == 'no' or num01 == 'NO':
                return data_list  # 直接返回data_list
            else:
                print('请输入正确的 yes 或 no，请重新输入')
                continue


def huoqu(data):
    # 获取音乐操作
    while True:
        try:
            go = int(input('请输入目前搜索到的音乐的开始序列号：'))
            ex = int(input('请输入目前搜索到的音乐的结束序列号：'))
            if 0 < go <= ex <= len(data):
                break
            else:
                print('输入的序列号超出范围或大小关系有误，请重新输入！')
        except ValueError as f:
            print('程序错误异常：', f)
    for i in range(go - 1, ex):
        yield data[i]


def cun(data):
    for i in data:
        # 这个url可以将包括了的付费音乐也获取过来(这是老接口，就不需要逆向js了，本人也没有去搞)
        url = f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={i[1]}&type=convert_url3&httpsStatus=1&reqId={i[0]}'
        json_get_url = json.loads(requests.get(url=url).text).get('data').get('url')
        get_mp3_url = requests.get(url=json_get_url)
        # 对文件命名格式的修改(部分音乐会出现特殊字符命名格式错误)
        character = ['/', '//', ':', '*', '?', '"', '<', '>', '|']
        for i1 in i[2]:
            if i1 in character:
                i[2] = i[2].replace(i1, '')
        if not os.path.exists(fr'D:\\爬取的数据\酷我音乐爬取\{i[3]}'):
            os.makedirs(fr'D:\\爬取的数据\酷我音乐爬取\{i[3]}')
        with open(fr'D:\\爬取的数据\酷我音乐爬取\{i[3]}\{i[2]}.mp3', 'wb') as f:
            f.write(get_mp3_url.content)
            print(f'成功获取：{i[3]}的{i[2]}')
        f.close()


def main():
    get_name = get()
    data_list = huoqu(get_name)
    cun(data_list)
    print('===============程序结束===============')


if __name__ == '__main__':
    main()
